// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object"){ // CommonJS
    mod(require("../../lib/codemirror"));
  } else if (typeof define == "function" && define.amd){ // AMD
    define(["../../lib/codemirror"], mod);
  } else { // Plain browser env
    mod(CodeMirror);
  }
})(function(CodeMirror) {
"use strict";
  CodeMirror.registerHelper("fold", "region", function(cm, start) {
    let lineNo = start.line;
    let line   = cm.getLine(lineNo);
    if(!line || !line.match(/\/\/[ |\t]*#region/)){
      return undefined;
    }
    let startPoint = line.length;
    let level = 1;
    let lastLineNo  = cm.lastLine();
    while(lineNo<lastLineNo){
      lineNo++;
      line = cm.getLine(lineNo);
      if(!line){continue;}
      if(line.match(/\/\/[ |\t]*#endregion/)){
        if(level==1){
          break;
        }else{
          level--;
        }
      }
      if(line.match(/\/\/[ |\t]*#region/)){
        level++;
      }
    }
    return {
      from: CodeMirror.Pos(start.line, startPoint),
      to: CodeMirror.Pos(lineNo, line.length)
    };
  });

  CodeMirror.defineExtension("foldRegionAll", function(isUnFold) {
    let that  = this;
    let count = this.lineCount();
    if(isUnFold){
      _doUnfold(count);
    }else{
      _doFold(count);
    }
    // 递归折叠全部代码
    function _doFold(lineCount,startLine){
      let isRoot = false;
      if(startLine==undefined){
        startLine = 0;
        isRoot    = true;
      }
      let regionLineNo;
      let lineCnt;
      while(startLine<lineCount){
        lineCnt = that.getLine(startLine);
        if(lineCnt){
          lineCnt = lineCnt.replace(/^\s+|\s+$/g, "").replace(/^\t+|\t+$/g, "");
        }else{
          startLine++;
          continue;
        }
        if(lineCnt.indexOf("//#region")==0){
          if(regionLineNo==undefined){
            regionLineNo = startLine;
            startLine = _doFold(lineCount,startLine+1);
            that.foldCode({line: regionLineNo, ch: 0}, null, "fold");
            regionLineNo = undefined;
            continue;
          }
        }else if(lineCnt.indexOf("//#endregion")==0){
          if(regionLineNo==undefined){
            startLine++;
            if(isRoot){
              // 如果是首层调用，在没有发现 //#region 时
              // 先发现了结束标识，忽略当前错误标识
              continue;
            }
            return startLine; // 如果是递归调用，返回上一层
          }else{
            // 同级发现了结束标识
            that.foldCode({line: regionLineNo, ch: 0}, null, "fold");
            regionLineNo = undefined;
            continue;
          }
        }else{
          startLine++;
          continue;
        }
      }
    }
    // 展开全部代码
    function _doUnfold(lineCount){
      let lineCnt;
      for(let i=0;i<lineCount;i++){
        lineCnt = that.getLine(i);
        if(lineCnt){
          lineCnt = lineCnt.replace(/^\s+|\s+$/g, "").replace(/^\t+|\t+$/g, "");
        }else{
          continue;
        }
        that.foldCode({line: i, ch: 0}, null, "unfold");
      }
    }
  });
});
